﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace EngineLayer
{
    using DBLayer;
    using EngineLayer.Services;
    using EngineLayer.Properties;
    using EngineLayer.Common;
    using System.IO;
    using EngineLayer.Model;

   public class UpdatesModel : DBEntities
    {
        FTPHandler ftp;
        Updates updates;
 //>>>>>>>>>>>
        DateTime LocalTimeStamp, OnlineTimeStamp;

        private string LatestOnline = "";
     
 
       private class FileList
        {
            public string FileName { get; set; }
            public DateTime date { get; set; }
        }
 // >>>>>>>>>>>>>>
        public UpdatesModel()
        {
            updates = new Updates();
        
            AddDefaultValues();

            DataSource = database.UpdateElement.OrderBy(h => h.Name);

            ftp = new FTPHandler(database.FTPServers.FirstOrDefault());
        }

        private void AddDefaultValues()
        {
                foreach(var elements in updates.ElementsAvailableToUpdate)
                    AddUpdateElement(elements.ElementName);   
        }
        
        private void AddUpdateElement(string ElementValue)
        {
            IFormatProvider culture = new CultureInfo(EngineResources.CultureInfoMX, true);

            if (!database.UpdateElement.Any(Any => Any.Name.Equals(ElementValue)))
            {
                UpdateElement updates = new UpdateElement();
                updates.Name = ElementValue;
                updates.Version = DateTime.ParseExact(EngineResources.UpdatesBaseDate, EngineResources.UpdatesFormat, culture);
                database.UpdateElement.AddObject(updates);
                database.SaveChanges();
            }
        }
        
        private static void UpdateTimeStamp(string Element, DateTime TimeStamp)
        {
            UpdateElement updateTimeStamp = database.UpdateElement.Where(n => n.Name == Element).FirstOrDefault();
            if (updateTimeStamp != null)
                updateTimeStamp.Version = TimeStamp;
            database.SaveChanges();
        }

        public bool ProcessUpdate(ElementsToUpdate elements)
        {
            Type T = this.updates.ElementsAvailableToUpdate.
                            Where(w => w.ElementName.Equals(elements.ToString()))
                            .Select(n => n.ElementType).FirstOrDefault();
    
           // Type t = T.Name;
           
            List<string> tt = new List<string>();
           if(CheckVersions(elements.ToString()))
                        tt = ftp.GetFileData(LatestOnline).Split(new[] { "\r\n" }, StringSplitOptions.None).ToList();
            
           //  UpdateTEST<t>(tt);
              
              //if (UpdateAvailable(PRODUCTOS))
              //  {
              //          productos.UpdateProducts(ftp.GetFileData(LatestOnline).Split(new[] { "\r\n" }, StringSplitOptions.None).ToList());

              //      UpdateElements.UpdateTimeStamp(PRODUCTOS, OnlineTimeStamp);
              //  }

            return true;
        }
     
        private bool CheckVersions(string elementToCheck)
        {
            string LatestFileName;

            try
            {
                LatestFileName = GetLatestVersionOnline(elementToCheck);

                OnlineTimeStamp = GetDateParsed(LatestFileName, elementToCheck);
                LocalTimeStamp = updates.GetLatestUpdateTimeStamp(ElementsToUpdate.PRODUCTOS);

                if (DateTime.Compare(LocalTimeStamp, OnlineTimeStamp) < 0)
                {
                    //hay updates disponibles!
                    LatestOnline = LatestFileName;
                    return true;
                }
                else
                {
                    //estas en la ultima Version
                    LatestOnline = "";
                  //  StatusBarInfo.Instance.SendStatusInfo("El catalogo local " + elementToCheck.ToString() + " ya esta en la ultima version");
                }
            }
            catch
            {
            //    StatusBarInfo.Instance.SendStatusInfo(MessageError.CheckVersionsError);
            }

            return false;
        }

        private DateTime GetDateParsed(string dateValue, string replace = "")
        {
            IFormatProvider culture = new CultureInfo("es-MX", true);

            if (!(replace == string.Empty))
            {
                dateValue = Path.GetFileNameWithoutExtension(dateValue).Replace(replace + "_", string.Empty);
            }

            return DateTime.ParseExact(dateValue,EngineResources.UpdatesFormat, culture);
        }
      
        private string GetLatestVersionOnline(string latestOnlineElement)
        {
            List<FileList> fileList = new List<FileList>();

            try
            {
                foreach (string data in ftp.GetFileList().Where(n => n.Contains(latestOnlineElement)).ToList())
                {
                    FileList fileData = new FileList();

                    fileData.FileName = data;
                    fileData.date = GetDateParsed(data, latestOnlineElement);

                    fileList.Add(fileData);
                }

                return fileList.Select(d => new
                {
                    d.date,
                    d.FileName
                })
                                         .Distinct()
                                         .OrderByDescending(d => d.date)
                                         .Select(d => d.FileName)
                                         .FirstOrDefault().ToString();
            }
            catch (Exception e)
            {
              //  StatusBarInfo.Instance.SendStatusInfo(e.Message);
                return "";
            }
        }
      
        private T UpdateTEST<T>(IEnumerable<string> TEXT)
        where T : DBLayer.Product // , new ()
        {


            return null;
        }
        
        //private void UpdateTEST<T>(IEnumerable<string> TEXT)
        //    where T : SystemUser
        //{


        //}

        //private void UpdateTEST<T>(IEnumerable<string> TEXT)
        //where T : Client
        //{


        //}
   }
}
